<template>
  <el-dialog
    v-model="visible"
    :title="`清洗列: ${column?.name || ''}`"
    width="800px"
    :before-close="handleClose">
    
    <div class="column-cleaning-dialog">
      <div v-if="column" class="cleaning-content">
        <!-- 列信息 -->
        <div class="column-info">
          <div class="info-header">
            <h4>列信息</h4>
          </div>
          <div class="info-content">
            <div class="info-item">
              <span class="label">列名:</span>
              <span class="value">{{ column.name }}</span>
            </div>
            <div class="info-item">
              <span class="label">数据类型:</span>
              <el-tag :type="getDataTypeColor(column.dataType)">{{ column.dataType }}</el-tag>
            </div>
            <div class="info-item">
              <span class="label">总行数:</span>
              <span class="value">{{ data.length }}</span>
            </div>
            <div class="info-item">
              <span class="label">空值:</span>
              <span class="value">{{ nullCount }} ({{ nullPercentage }}%)</span>
            </div>
            <div class="info-item">
              <span class="label">唯一值:</span>
              <span class="value">{{ uniqueCount }}</span>
            </div>
          </div>
        </div>
        
        <!-- 清洗选项 -->
        <div class="cleaning-options">
          <div class="options-header">
            <h4>清洗选项</h4>
          </div>
          
          <el-form :model="cleaningConfig" label-width="120px" size="default">
            <!-- 空值处理 -->
            <el-form-item label="空值处理">
              <el-radio-group v-model="cleaningConfig.nullHandling">
                <el-radio value="keep">保持原样</el-radio>
                <el-radio value="remove">删除行</el-radio>
                <el-radio value="fill">填充值</el-radio>
                <el-radio value="interpolate">插值</el-radio>
              </el-radio-group>
            </el-form-item>
            
            <el-form-item v-if="cleaningConfig.nullHandling === 'fill'" label="填充值">
              <el-input v-model="cleaningConfig.fillValue" placeholder="输入填充值" />
            </el-form-item>
            
            <!-- 文本清洗 -->
            <div v-if="column.dataType === 'text'" class="text-cleaning">
              <el-form-item label="文本清洗">
                <el-checkbox-group v-model="cleaningConfig.textOperations">
                  <el-checkbox value="trim">去除首尾空格</el-checkbox>
                  <el-checkbox value="lowercase">转小写</el-checkbox>
                  <el-checkbox value="uppercase">转大写</el-checkbox>
                  <el-checkbox value="removeSpecial">移除特殊字符</el-checkbox>
                  <el-checkbox value="standardize">标准化格式</el-checkbox>
                </el-checkbox-group>
              </el-form-item>
            </div>
            
            <!-- 数值清洗 -->
            <div v-if="column.dataType === 'number' || column.dataType === 'currency'" class="number-cleaning">
              <el-form-item label="数值清洗">
                <el-checkbox-group v-model="cleaningConfig.numberOperations">
                  <el-checkbox value="removeOutliers">移除异常值</el-checkbox>
                  <el-checkbox value="round">四舍五入</el-checkbox>
                  <el-checkbox value="normalize">标准化</el-checkbox>
                </el-checkbox-group>
              </el-form-item>
              
              <el-form-item v-if="cleaningConfig.numberOperations.includes('round')" label="小数位数">
                <el-input-number v-model="cleaningConfig.decimalPlaces" :min="0" :max="10" />
              </el-form-item>
              
              <el-form-item label="数值范围">
                <div class="range-inputs">
                  <el-input-number v-model="cleaningConfig.minValue" placeholder="最小值" />
                  <span>至</span>
                  <el-input-number v-model="cleaningConfig.maxValue" placeholder="最大值" />
                </div>
              </el-form-item>
            </div>
            
            <!-- 日期清洗 -->
            <div v-if="column.dataType === 'date'" class="date-cleaning">
              <el-form-item label="日期格式">
                <el-select v-model="cleaningConfig.dateFormat">
                  <el-option label="YYYY-MM-DD" value="YYYY-MM-DD" />
                  <el-option label="MM/DD/YYYY" value="MM/DD/YYYY" />
                  <el-option label="DD/MM/YYYY" value="DD/MM/YYYY" />
                  <el-option label="YYYY年MM月DD日" value="YYYY年MM月DD日" />
                </el-select>
              </el-form-item>
              
              <el-form-item label="日期范围">
                <el-date-picker
                  v-model="cleaningConfig.dateRange"
                  type="daterange"
                  range-separator="至"
                  start-placeholder="开始日期"
                  end-placeholder="结束日期" />
              </el-form-item>
            </div>
            
            <!-- 自定义规则 -->
            <el-form-item label="自定义规则">
              <el-input
                v-model="cleaningConfig.customRule"
                type="textarea"
                :rows="3"
                placeholder="输入自定义清洗规则 (JavaScript表达式)" />
            </el-form-item>
          </el-form>
        </div>
        
        <!-- 预览结果 -->
        <div class="preview-section">
          <div class="preview-header">
            <h4>清洗预览</h4>
            <el-button size="small" @click="previewCleaning">
              <el-icon><View /></el-icon>
              预览
            </el-button>
          </div>
          
          <div v-if="previewData.length > 0" class="preview-content">
            <div class="preview-stats">
              <div class="stat-item">
                <span class="stat-label">原始数据:</span>
                <span class="stat-value">{{ data.length }} 行</span>
              </div>
              <div class="stat-item">
                <span class="stat-label">清洗后:</span>
                <span class="stat-value">{{ previewData.length }} 行</span>
              </div>
              <div class="stat-item">
                <span class="stat-label">变更:</span>
                <span class="stat-value">{{ changedCount }} 个值</span>
              </div>
            </div>
            
            <div class="preview-table">
              <el-table :data="previewData.slice(0, 10)" style="width: 100%" size="small">
                <el-table-column label="行号" type="index" width="60" />
                <el-table-column label="原始值" prop="original" width="200">
                  <template #default="{ row }">
                    <span :class="{ 'changed-value': row.changed }">{{ row.original }}</span>
                  </template>
                </el-table-column>
                <el-table-column label="清洗后" prop="cleaned" width="200">
                  <template #default="{ row }">
                    <span :class="{ 'changed-value': row.changed }">{{ row.cleaned }}</span>
                  </template>
                </el-table-column>
                <el-table-column label="状态" width="100">
                  <template #default="{ row }">
                    <el-tag v-if="row.changed" type="warning" size="small">已修改</el-tag>
                    <el-tag v-else type="success" size="small">无变化</el-tag>
                  </template>
                </el-table-column>
              </el-table>
            </div>
          </div>
        </div>
      </div>
    </div>
    
    <template #footer>
      <div class="dialog-footer">
        <el-button @click="handleClose">取消</el-button>
        <el-button @click="previewCleaning">预览</el-button>
        <el-button type="primary" @click="applyCleaning" :loading="applying">
          应用清洗
        </el-button>
      </div>
    </template>
  </el-dialog>
</template>

<script setup>
import { ref, computed, watch } from 'vue'
import { ElMessage } from 'element-plus'
import { View } from '@element-plus/icons-vue'

const props = defineProps({
  modelValue: {
    type: Boolean,
    default: false
  },
  column: {
    type: Object,
    default: null
  },
  data: {
    type: Array,
    default: () => []
  }
})

const emit = defineEmits(['update:modelValue', 'cleaned'])

// 响应式数据
const visible = ref(false)
const applying = ref(false)
const previewData = ref([])
const changedCount = ref(0)

const cleaningConfig = ref({
  nullHandling: 'keep',
  fillValue: '',
  textOperations: [],
  numberOperations: [],
  decimalPlaces: 2,
  minValue: null,
  maxValue: null,
  dateFormat: 'YYYY-MM-DD',
  dateRange: null,
  customRule: ''
})

// 计算属性
const columnValues = computed(() => {
  if (!props.column || !props.data) return []
  return props.data.map(row => row[props.column.field])
})

const nullCount = computed(() => {
  return columnValues.value.filter(value => value == null || value === '').length
})

const nullPercentage = computed(() => {
  if (columnValues.value.length === 0) return 0
  return Math.round((nullCount.value / columnValues.value.length) * 100)
})

const uniqueCount = computed(() => {
  const uniqueValues = new Set(columnValues.value.filter(value => value != null && value !== ''))
  return uniqueValues.size
})

// 监听器
watch(() => props.modelValue, (val) => {
  visible.value = val
  if (val) {
    resetConfig()
  }
})

watch(visible, (val) => {
  emit('update:modelValue', val)
})

// 方法
const resetConfig = () => {
  cleaningConfig.value = {
    nullHandling: 'keep',
    fillValue: '',
    textOperations: [],
    numberOperations: [],
    decimalPlaces: 2,
    minValue: null,
    maxValue: null,
    dateFormat: 'YYYY-MM-DD',
    dateRange: null,
    customRule: ''
  }
  previewData.value = []
  changedCount.value = 0
}

const getDataTypeColor = (dataType) => {
  const colors = {
    'text': 'info',
    'number': 'warning',
    'currency': 'success',
    'date': 'primary',
    'boolean': 'danger'
  }
  return colors[dataType] || 'info'
}

const previewCleaning = () => {
  if (!props.column || !props.data) return
  
  const results = []
  let changed = 0
  
  props.data.forEach((row, index) => {
    const originalValue = row[props.column.field]
    const cleanedValue = cleanValue(originalValue)
    const hasChanged = originalValue !== cleanedValue
    
    if (hasChanged) changed++
    
    results.push({
      index,
      original: originalValue,
      cleaned: cleanedValue,
      changed: hasChanged
    })
  })
  
  previewData.value = results
  changedCount.value = changed
  
  ElMessage.success(`预览完成，共 ${changed} 个值将被修改`)
}

const cleanValue = (value) => {
  let cleaned = value
  
  // 处理空值
  if (cleaned == null || cleaned === '') {
    switch (cleaningConfig.value.nullHandling) {
      case 'fill':
        cleaned = cleaningConfig.value.fillValue
        break
      case 'remove':
        return null // 标记为删除
      default:
        return cleaned
    }
  }
  
  // 文本清洗
  if (props.column.dataType === 'text' && cleaned != null) {
    cleaned = String(cleaned)
    
    if (cleaningConfig.value.textOperations.includes('trim')) {
      cleaned = cleaned.trim()
    }
    
    if (cleaningConfig.value.textOperations.includes('lowercase')) {
      cleaned = cleaned.toLowerCase()
    }
    
    if (cleaningConfig.value.textOperations.includes('uppercase')) {
      cleaned = cleaned.toUpperCase()
    }
    
    if (cleaningConfig.value.textOperations.includes('removeSpecial')) {
      cleaned = cleaned.replace(/[^\w\s\u4e00-\u9fff]/g, '')
    }
    
    if (cleaningConfig.value.textOperations.includes('standardize')) {
      // 标准化：去除多余空格，统一格式
      cleaned = cleaned.replace(/\s+/g, ' ').trim()
    }
  }
  
  // 数值清洗
  if ((props.column.dataType === 'number' || props.column.dataType === 'currency') && cleaned != null) {
    const numValue = Number(cleaned)
    
    if (!isNaN(numValue)) {
      cleaned = numValue
      
      if (cleaningConfig.value.numberOperations.includes('round')) {
        cleaned = Number(cleaned.toFixed(cleaningConfig.value.decimalPlaces))
      }
      
      // 范围检查
      if (cleaningConfig.value.minValue != null && cleaned < cleaningConfig.value.minValue) {
        cleaned = cleaningConfig.value.minValue
      }
      
      if (cleaningConfig.value.maxValue != null && cleaned > cleaningConfig.value.maxValue) {
        cleaned = cleaningConfig.value.maxValue
      }
      
      // 异常值处理
      if (cleaningConfig.value.numberOperations.includes('removeOutliers')) {
        // 简化的异常值检测
        const values = columnValues.value.filter(v => !isNaN(Number(v))).map(Number)
        const mean = values.reduce((sum, v) => sum + v, 0) / values.length
        const std = Math.sqrt(values.reduce((sum, v) => sum + Math.pow(v - mean, 2), 0) / values.length)
        
        if (Math.abs(cleaned - mean) > 3 * std) {
          cleaned = mean // 用均值替换异常值
        }
      }
    }
  }
  
  // 日期清洗
  if (props.column.dataType === 'date' && cleaned != null) {
    try {
      const date = new Date(cleaned)
      if (!isNaN(date.getTime())) {
        // 格式化日期
        switch (cleaningConfig.value.dateFormat) {
          case 'YYYY-MM-DD':
            cleaned = date.toISOString().split('T')[0]
            break
          case 'MM/DD/YYYY':
            cleaned = `${(date.getMonth() + 1).toString().padStart(2, '0')}/${date.getDate().toString().padStart(2, '0')}/${date.getFullYear()}`
            break
          case 'DD/MM/YYYY':
            cleaned = `${date.getDate().toString().padStart(2, '0')}/${(date.getMonth() + 1).toString().padStart(2, '0')}/${date.getFullYear()}`
            break
          case 'YYYY年MM月DD日':
            cleaned = `${date.getFullYear()}年${(date.getMonth() + 1).toString().padStart(2, '0')}月${date.getDate().toString().padStart(2, '0')}日`
            break
        }
        
        // 日期范围检查
        if (cleaningConfig.value.dateRange && cleaningConfig.value.dateRange.length === 2) {
          const [startDate, endDate] = cleaningConfig.value.dateRange
          if (date < startDate || date > endDate) {
            cleaned = null // 超出范围的日期设为空
          }
        }
      }
    } catch (error) {
      cleaned = null // 无效日期设为空
    }
  }
  
  // 自定义规则
  if (cleaningConfig.value.customRule && cleaned != null) {
    try {
      // 简化的自定义规则执行
      const func = new Function('value', `return ${cleaningConfig.value.customRule}`)
      cleaned = func(cleaned)
    } catch (error) {
      console.warn('自定义规则执行失败:', error)
    }
  }
  
  return cleaned
}

const applyCleaning = async () => {
  if (previewData.value.length === 0) {
    ElMessage.warning('请先预览清洗结果')
    return
  }
  
  applying.value = true
  
  try {
    // 应用清洗结果
    const cleanedData = previewData.value.map(item => ({
      index: item.index,
      value: item.cleaned
    }))
    
    emit('cleaned', {
      column: props.column,
      cleanedData,
      config: cleaningConfig.value,
      stats: {
        totalRows: props.data.length,
        changedRows: changedCount.value,
        nullCount: nullCount.value
      }
    })
    
    ElMessage.success('列清洗完成')
    handleClose()
  } catch (error) {
    console.error('清洗失败:', error)
    ElMessage.error('清洗失败')
  } finally {
    applying.value = false
  }
}

const handleClose = () => {
  visible.value = false
}
</script>

<style scoped>
.column-cleaning-dialog {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.column-info {
  border: 1px solid #e4e7ed;
  border-radius: 6px;
  padding: 16px;
  background: #f8f9fa;
}

.info-header h4 {
  margin: 0 0 12px 0;
  color: #303133;
  font-size: 16px;
}

.info-content {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 12px;
}

.info-item {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.label {
  font-size: 12px;
  color: #606266;
}

.value {
  font-weight: 600;
  color: #303133;
}

.cleaning-options {
  border: 1px solid #e4e7ed;
  border-radius: 6px;
  padding: 16px;
}

.options-header h4 {
  margin: 0 0 16px 0;
  color: #303133;
  font-size: 16px;
}

.range-inputs {
  display: flex;
  align-items: center;
  gap: 8px;
}

.range-inputs span {
  color: #606266;
  font-size: 12px;
}

.preview-section {
  border: 1px solid #e4e7ed;
  border-radius: 6px;
  padding: 16px;
}

.preview-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px;
}

.preview-header h4 {
  margin: 0;
  color: #303133;
  font-size: 16px;
}

.preview-stats {
  display: flex;
  gap: 24px;
  margin-bottom: 16px;
  padding: 12px;
  background: #f8f9fa;
  border-radius: 4px;
}

.stat-item {
  display: flex;
  gap: 8px;
  align-items: center;
}

.stat-label {
  font-size: 12px;
  color: #606266;
}

.stat-value {
  font-weight: 600;
  color: #303133;
}

.preview-table {
  border: 1px solid #e4e7ed;
  border-radius: 4px;
}

.changed-value {
  background: #fff3cd;
  padding: 2px 4px;
  border-radius: 3px;
}

.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
}
</style>

